package com.kaxiu.web.wx;

import com.kaxiu.common.base.AbstractBaseController;
import com.kaxiu.config.wx.ma.WxMaConfiguration;
import com.kaxiu.config.wx.ma.WxMaProperties;
import com.kaxiu.config.shiro.jwt.JwtConfig;
import com.kaxiu.config.shiro.jwt.JwtToken;
import com.kaxiu.persistent.entity.BasicUser;
import com.kaxiu.service.IBasicUserService;
import com.kaxiu.vo.ResultDataWrap;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
import me.chanjar.weixin.common.error.WxErrorException;

import javax.annotation.Resource;
import java.util.HashMap;

/**
 * 微信小程序用户接口
 *
 * @author <a href="https://github.com/binarywang">Binary Wang</a>
 */
@RestController
@RequestMapping("/wx/{appid}/user/")
public class WxMaUserController extends AbstractBaseController {

    @Resource
    private JwtConfig jwtConfig;

    @Resource
    private IBasicUserService userService;

    @Resource
    private WxMaProperties properties;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 登陆接口
     */
    @GetMapping("/login")
    public ResultDataWrap login(@PathVariable String appid, String code) {
        if (StringUtils.isBlank(code)) {
            return buildFailResult("empty jscode");
        }

        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        try {
            WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
            this.logger.info(session.getSessionKey());
            this.logger.info(session.getOpenid());
            String token = jwtConfig.createTokenByWxAccount(session);
            return buildResult(token);
        } catch (WxErrorException e) {
            this.logger.error(e.getMessage(), e);
            return buildFailResult();
        }
    }

    /**
     * <pre>
     * 获取用户信息接口
     * </pre>
     */
    @GetMapping("/info")
    public ResultDataWrap info(@PathVariable String appid,
                       String signature, String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        JwtToken token = (JwtToken) SecurityUtils.getSubject().getPrincipal();
        String sessionKey = jwtConfig.getSessionKeyByToken(token.getToken());

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return buildFailResult("user check failed");
        }

        // 解密用户信息
        WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);

        Integer roleId = this.properties.getConfigs().stream().filter( e -> appid.equals(e.getAppid())).findFirst().orElseThrow(()->
                new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置，请核实！", appid))
        ).getRoleId();

        BasicUser user = userService.saveBasicUser(convertUser(userInfo, appid), roleId);
        HashMap<String, Object> result = new HashMap<>(8);
        result.put("nickName", user.getNickname());
        result.put("avatar", user.getAvatar());
        result.put("auditStatus", user.getAuditStatus());
        result.put("mobile", user.getMobile());
        result.put("id", user.getId());
        return buildResult(result);
    }

    /**
     * <pre>
     * 获取用户绑定手机号信息
     * </pre>
     */
    @GetMapping("/phone")
    public ResultDataWrap phone(@PathVariable String appid, String sessionKey, String signature,
                        String rawData, String encryptedData, String iv) {
        final WxMaService wxService = WxMaConfiguration.getMaService(appid);

        // 用户信息校验
        if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
            return buildFailResult("user check failed");
        }

        // 解密
        WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);

        return buildResult(phoneNoInfo);
    }

    private BasicUser convertUser(WxMaUserInfo userInfo, String appid){
        BasicUser user = new BasicUser();
        user.setOpenId(userInfo.getOpenId());
        user.setNickname(userInfo.getNickName());
        user.setGender(Integer.valueOf(userInfo.getGender()));
        user.setLanguage(userInfo.getLanguage());
        user.setCity(userInfo.getCity());
        user.setProvince(userInfo.getProvince());
        user.setCountry(userInfo.getCountry());
        user.setAvatar(userInfo.getAvatarUrl());
        user.setUnionId(userInfo.getUnionId());
        user.setAppId(appid);
        return user;
    }

}
